#ifndef COMMON_LOG_H_
#define COMMON_LOG_H_

#include <chrono>
#include <cstdarg>
#include <mutex>
#include <string>

#include "glog/logging.h"
#include "glog/raw_logging.h"
#if 0
static inline std::string GetCurrentTimeAsString(const std::string &format = "%F %T") {
   auto now = std::chrono::system_clock::now();
   auto in_time_t = std::chrono::system_clock::to_time_t(now);
   char buf[64];
   std::strftime(buf, sizeof(buf), format.c_str(), std::localtime(&in_time_t));
   return buf;
}
#endif


static std::string GetProcessName() {

   static std::string process_name;
   if (!process_name.empty()) {
       return process_name;
   }
   char buffer[1024];
   ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1);
   if (len != -1) {
       buffer[len] = '\0';
       // 使用 basename 函数获取进程名
       process_name = basename(buffer);
   } else {
       process_name = "Unknown";
   }
   return process_name;
}

#ifndef LEFT_BRACKET
#define LEFT_BRACKET "["
#endif

#ifndef RIGHT_BRACKET
#define RIGHT_BRACKET "]"
#endif

#ifndef TIME_NOW
//#define TIME_NOW GetCurrentTimeAsString()
#define TIME_NOW ""
#endif

#ifndef MODULE_NAME
#define MODULE_NAME GetProcessName()
#endif

#ifndef LOG_DEBUG
#define LOG_DEBUG(module) \
   VLOG(4) << LEFT_BRACKET << module << RIGHT_BRACKET << "[DEBUG] "
#endif

#ifndef LOGD
#define LOGD LOG_DEBUG(MODULE_NAME)
#endif

using google::ERROR;
using google::FATAL;
using google::INFO;
using google::WARNING;

#ifndef LOGI
#define LOGI LOG_MODULE(MODULE_NAME, INFO)
#endif

#ifndef LOGW
#define LOGW LOG_MODULE(MODULE_NAME, WARNING)
#endif

#ifndef LOGE
#define LOGE LOG_MODULE(MODULE_NAME, ERROR)
#endif

#ifndef LOGFATAL
#define LOGFATAL LOG_MODULE(MODULE_NAME, FATAL)
#endif

#ifndef LOG_MODULE
#define LOG_MODULE(module, log_severity) \
   LOG(log_severity) << LEFT_BRACKET << module << RIGHT_BRACKET
#endif

#ifndef LOGI_IF
#define LOGI_IF(cond) PLOG_IF(INFO, cond, MODULE_NAME)
#endif
#ifndef LOGW_IF
#define LOGW_IF(cond) PLOG_IF(WARN, cond, MODULE_NAME)
#endif
#ifndef LOGE_IF
#define LOGE_IF(cond) PLOG_IF(ERROR, cond, MODULE_NAME)
#endif
#ifndef LOGFATAL_IF
#define LOGFATAL_IF(cond) PLOG_IF(FATAL, cond, MODULE_NAME)
#endif

#if !defined(LOG_IF)
#define PLOG_IF(severity, cond, module) \
   !(cond) ? (void) 0                  \
           : google::LogMessageVoidify() & LOG_MODULE(module, severity)
#endif

#if !defined(CHECK)
#define CHECK(cond) \
   CHECK(cond) << TIME_NOW << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
#endif

#define PLOGI_EVERY(freq) \
   LOG_EVERY_N(INFO, freq) << TIME_NOW << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
#define PLOGW_EVERY(freq)      \
   LOG_EVERY_N(WARNING, freq) \
           << TIME_NOW << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET
#define PLOGE_EVERY(freq) \
   LOG_EVERY_N(ERROR, freq) << TIME_NOW << LEFT_BRACKET << MODULE_NAME << RIGHT_BRACKET

#if !defined(LOG_RETURN_IF_NULL)
#define LOG_RETURN_IF_NULL(ptr)         \
   if (ptr == nullptr) {               \
       LOGW << #ptr << " is nullptr."; \
       return;                         \
   }
#endif

#if !defined(LOG_RETURN_VAL_IF_NULL)
#define LOG_RETURN_VAL_IF_NULL(ptr, val) \
   if (ptr == nullptr) {                \
       LOGW << #ptr << " is nullptr.";  \
       return val;                      \
   }
#endif

#if !defined(LOG_RETURN_IF)
#define LOG_RETURN_IF(condition)          \
   if (condition) {                      \
       LOGW << #condition << " is met."; \
       return;                           \
   }
#endif

#if !defined(LOG_RETURN_VAL_IF)
#define LOG_RETURN_VAL_IF(condition, val) \
   if (condition) {                      \
       LOGW << #condition << " is met."; \
       return val;                       \
   }
#endif

#if !defined(_LOG_RETURN_VAL_IF_NULL2__)
#define _LOG_RETURN_VAL_IF_NULL2__
#define LOG_RETURN_VAL_IF_NULL2(ptr, val) \
   if (ptr == nullptr) {                 \
       return (val);                     \
   }
#endif

#if !defined(_LOG_RETURN_VAL_IF2__)
#define _LOG_RETURN_VAL_IF2__
#define LOG_RETURN_VAL_IF2(condition, val) \
   if (condition) {                       \
       return (val);                      \
   }
#endif

#if !defined(_LOG_RETURN_IF2__)
#define _LOG_RETURN_IF2__
#define LOG_RETURN_IF2(condition) \
   if (condition) {              \
       return;                   \
   }
#endif

#if !defined(LOG_ASSERT)
#define LOG_ASSERT(condition) \
   LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
#endif

#ifndef LOG_PERF
#define LOG_PERF VLOG(8) << TIME_NOW << "[PERF] "
#endif

#endif// COMMON_LOG_H_